/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.repair.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.repair.dto.SimpleElevatorPlanInfoDTO;
import org.springblade.modules.repair.entity.*;
import org.springblade.modules.repair.enums.MaintainPlanContentEnum;
import org.springblade.modules.repair.enums.StatusEnum;
import org.springblade.modules.repair.enums.TaskStatusEnum;
import org.springblade.modules.repair.service.*;
import org.springblade.modules.repair.vo.*;
import org.springblade.modules.repair.mapper.MaintainPlanCheckMapper;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.modules.repair.vo.plan.CheckChildPlanListVo;
import org.springblade.modules.repair.vo.plan.CheckChildPlanVo;
import org.springblade.modules.system.entity.Dict;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IDictService;
import org.springblade.modules.system.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 质检工单表 服务实现类
 *
 * @author ysq
 * @since 2023-11-27
 */
@Service
public class MaintainPlanCheckServiceImpl extends BaseServiceImpl<MaintainPlanCheckMapper, MaintainPlanCheck> implements IMaintainPlanCheckService {

	@Autowired
	private IMaintainPlanContentService maintainPlanContentService;

	@Autowired
	private IMaintainPlanContentUserService maintainPlanContentUserService;

	@Autowired
	private IMaintainMalfunctionHistoryService malfunctionHistoryService;

	@Autowired
	private IMaintainSignService maintainSignService;

	@Autowired
	private IMaintainPlanContentExtService maintainPlanContentExtService;

	@Autowired
	private IMaintainMalfunctionLogService malfunctionLogService;

	@Autowired
	private IMaintainMalfunctionHistoryService maintainMalfunctionHistoryService;

	@Autowired
	private IDictService dictService;

	@Autowired
	private MaintainMsgService msgService;

	@Autowired
	private IUserService userService;

	@Autowired
	private IElevatorService elevatorService;

	@Autowired
	private IWxFaultCauseService wxFaultCauseService;


	@Autowired
	private IWxFaultTypeService wxFaultTypeService;

	@Override
	public MaintainPlanCheckVO detail(Long planId) {

		MaintainPlanCheckVO detail = baseMapper.selectDetail(planId);
		if (Func.isEmpty(detail)) {
			throw new ServiceException("未找到对应工单");
		}
		// 查询该任务电梯最近一次完成的任务
		LastPlanVO lastPlanVO = maintainPlanContentService.selectElevatorLastPlan(detail.getElevatorId(), planId);
		detail.setLastPlan(lastPlanVO);

		// 查询关联人员信息
		List<MaintainPlanContentUser> planContentUsers = maintainPlanContentUserService.listUserByPlan(planId);
		detail.setPlanContentUsers(planContentUsers);

		// 查询操作记录
		List<MalFunctionHistoryVO> malFunctionHistories = malfunctionHistoryService.selectByPlanId(planId);
		detail.setMalFunctionHistories(malFunctionHistories);

		// 当前用户是否已签到
		Long currentUser = AuthUtil.getUserId();
		List<MaintainSign> list = maintainSignService.list(new LambdaQueryWrapper<MaintainSign>()
			.eq(MaintainSign::getPlanId, planId)
			.eq(MaintainSign::getUserId, currentUser)
		);
		detail.setIsSign(list.size() > 0);

		// 获取当天本人同一台梯是否存在签到记录的签到图片
		ElevatorLastPlanVO lastSignImg = maintainSignService.selectUserLastSignImgByElevator(AuthUtil.getUserId(), detail.getElevatorId());
		detail.setLastSignImg(lastSignImg);

		List<MalFunctionHistoryVO> malFunctionHistoryVOS = maintainMalfunctionHistoryService.selectByPlanId(planId);
		if (Func.isNotEmpty(malFunctionHistoryVOS)) {
			Map<Long, List<WxFaultCause>> wxFaultCauseMap = wxFaultCauseService.list().stream().collect(Collectors.groupingBy(WxFaultCause::getId));
			Map<Long, List<WxFaultType>> wxFaultTypeMap = wxFaultTypeService.list().stream().collect(Collectors.groupingBy(WxFaultType::getId));
			for (MalFunctionHistoryVO malFunctionHistoryVO : malFunctionHistoryVOS) {
				if (malFunctionHistoryVO.getChildPlanId() != null) {
					malFunctionHistoryVO.setCheckChildPlan(getCheckChildPlanVo(malFunctionHistoryVO.getChildPlanId()));
				}
				//处理原因
				String faultReasonKey = malFunctionHistoryVO.getFaultReasonKey();
				if (StrUtil.isNotEmpty(faultReasonKey)) {
					List<String> ids = Arrays.asList(faultReasonKey.split(","));
					List<String> wxFaultCauseNames = new ArrayList<>(10);
					for (String id : ids) {
						List<WxFaultCause> wxFaultCauses = wxFaultCauseMap.get(Convert.toLong(id));
						if (wxFaultCauses != null && wxFaultCauses.size() > 0) {
							wxFaultCauseNames.add(wxFaultCauses.get(0).getFaultName());
						}
					}
					malFunctionHistoryVO.setWxFaultCauseNames(wxFaultCauseNames);
				}
				//处理故障责任
				 String faultReasonWhoKey = malFunctionHistoryVO.getFaultReasonWhoKey();
				if (StrUtil.isNotEmpty(faultReasonWhoKey)) {
					List<String> ids = Arrays.asList(faultReasonWhoKey.split(","));
					List<String> wxFaultTypeNames = new ArrayList<>(10);
					for (String id : ids) {
						List<WxFaultType> wxFaultTypes = wxFaultTypeMap.get(Convert.toLong(id));
						if (wxFaultTypes != null && wxFaultTypes.size() > 0) {
							wxFaultTypeNames.add(wxFaultTypes.get(0).getName());
						}
					}
					malFunctionHistoryVO.setWxFaultTypeNames(wxFaultTypeNames);
				}
			}
			detail.setMaintainMalfunctionHistories(malFunctionHistoryVOS);
		}

//		//表示不通过
//		Integer checkStatus = 2;
//		if (Convert.toInt(detail.getCheckStatus(), -1).equals(checkStatus)) {
//			List<MalFunctionHistoryVO> malFunctionHistoryVOS = maintainMalfunctionHistoryService.selectByPlanId(planId);
//
//			for (MalFunctionHistoryVO malFunctionHistoryVO : malFunctionHistoryVOS) {
//				if (malFunctionHistoryVO.getChildPlanId() != null) {
//					malFunctionHistoryVO.setCheckChildPlan(getCheckChildPlanVo(malFunctionHistoryVO.getChildPlanId()));
//				}
//			}
//			detail.setMaintainMalfunctionHistories(malFunctionHistoryVOS);
//		}

		List<CheckChildPlanListVo> checkChildPlanList = getCheckChildPlanList(planId);
		List<CheckChildPlanListVo> listVos = checkChildPlanList.stream().filter(o -> o.getStatus() == TaskStatusEnum.WX_TO_START.getStatus() || o.getStatus() == TaskStatusEnum.WX_UNDER_WAY.getStatus() || o.getStatus() == TaskStatusEnum.WX_ALLOCATION.getStatus()).collect(Collectors.toList());
		if (listVos == null || listVos.size() == 0) {
			detail.setChildPlanSize(0);
		} else {
			detail.setChildPlanSize(listVos.size());
		}

		return detail;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean finish(MaintainPlanCheck maintainPlanCheck) {

		//为前端增加缓存
		if (Convert.toInt(maintainPlanCheck.getStatus(), -1) == StatusEnum.DISABLE.getId()) {
			this.updateById(maintainPlanCheck);
			return true;
		}
		Long planId = maintainPlanCheck.getPlanId();
		MaintainPlanContent maintainPlanContent = maintainPlanContentService.getById(planId);
		if (Func.isEmpty(maintainPlanContent)) {
			throw new ServiceException("未找到对应工单");
		}
		if (maintainPlanContent.getStatus().equals(TaskStatusEnum.ZJ_SIGN_FINISH.getStatus())) {
			throw new ServiceException("工单状态已变更，请刷新页面");
		}
		if (!maintainPlanContent.getStatus().equals(TaskStatusEnum.ZJ_UNDER_WAY.getStatus())) {
			throw new ServiceException("工单状态异常，请刷新页面");
		}

		// 系统代签 任务提交时 未签退人员自动签退
		maintainSignService.checkUserSignOut(planId);


		maintainPlanContent.setStatus(TaskStatusEnum.ZJ_SIGN_FINISH.getStatus());
		maintainPlanContentService.updateById(maintainPlanContent);
		MaintainPlanContentExt planContentExt = maintainPlanContentExtService.getOne(Wrappers.<MaintainPlanContentExt>lambdaQuery().eq(MaintainPlanContentExt::getPlanId, planId));
		long workMinute = DateUtil.between(planContentExt.getPlanBeginTime(), DateUtil.date(), DateUnit.MINUTE);
		planContentExt.setWorkMinute((int) workMinute);
		planContentExt.setPlanEndTime(DateUtil.date());
		maintainPlanContentExtService.updateById(planContentExt);

		maintainPlanContentUserService.updateRescuePlanUserSignInfo(planId);

		// 插入工单记录
		malfunctionLogService.insertWorkLog(planId, TaskStatusEnum.getTaskName(maintainPlanContent.getTypeStatus(), maintainPlanContent.getStatus()), maintainPlanContent.getStatus());

		//统计问题点数量
		int size = maintainMalfunctionHistoryService.list(Wrappers.<MaintainMalfunctionHistory>lambdaQuery().eq(MaintainMalfunctionHistory::getPlanId, planId)).size();
		maintainPlanCheck.setProblemCounts(size);
		//发送消息
		if (size > 0) {
			SimpleElevatorPlanInfoDTO simpleElevatorPlanInfo = elevatorService.getSimpleElevatorPlanInfo(maintainPlanContent.getElevatorId());
			List<User> list1 = userService.getUserListOfRoleCode("inspectionHome", AuthUtil.getTenantId());
			List<User> list2 = userService.getUserListOfRoleCode("myApprove_edit", AuthUtil.getTenantId());
			List<User> list = list1.stream()
				.filter(list2::contains)
				.collect(Collectors.toList());
			List<Long> userIds = list.stream().map(User::getId).collect(Collectors.toList());
			MaintainMsg msg = new MaintainMsg();
			msg.setTitle(simpleElevatorPlanInfo.getBuildingName() + "-" + simpleElevatorPlanInfo.getElevatorAddress());
			msg.setContent("[质检工单完成] 有问题需要整改处理");
			msg.setType(MaintainPlanContentEnum.MAINTAIN_CHECK.getId());
			msg.setOtherId(planId);
			msgService.sendWebMsg(msg, userIds);
		}

//		//表示通过
//		Integer checkStatus = 1;
//		//如果通过状态删除问题点记录
//		if (maintainPlanCheck.getCheckStatus().equals(checkStatus)) {
//			maintainMalfunctionHistoryService.remove(Wrappers.<MaintainMalfunctionHistory>lambdaQuery().eq(MaintainMalfunctionHistory::getPlanId, planId));
//		} else {
//			//不通过统计问题点数量
//			int size = maintainMalfunctionHistoryService.list(Wrappers.<MaintainMalfunctionHistory>lambdaQuery().eq(MaintainMalfunctionHistory::getPlanId, planId)).size();
//			maintainPlanCheck.setProblemCounts(size);
//			//发送消息
//			if (size > 0) {
//				SimpleElevatorPlanInfoDTO simpleElevatorPlanInfo = elevatorService.getSimpleElevatorPlanInfo(maintainPlanContent.getElevatorId());
//				List<User> list1 = userService.getUserListOfRoleCode("inspectionHome", AuthUtil.getTenantId());
//				List<User> list2 = userService.getUserListOfRoleCode("myApprove_edit", AuthUtil.getTenantId());
//				List<User> list = list1.stream()
//					.filter(list2::contains)
//					.collect(Collectors.toList());
//				List<Long> userIds = list.stream().map(User::getId).collect(Collectors.toList());
//				MaintainMsg msg = new MaintainMsg();
//				msg.setTitle(simpleElevatorPlanInfo.getBuildingName() + "-" + simpleElevatorPlanInfo.getElevatorAddress());
//				msg.setContent("[质检工单完成] 有问题需要整改处理");
//				msg.setType(MaintainPlanContentEnum.MAINTAIN_CHECK.getId());
//				msg.setOtherId(planId);
//				msgService.sendWebMsg(msg, userIds);
//			}
//		}

		//更新质检工单的质检状态
		this.updateById(maintainPlanCheck);

		return true;
	}

	@Override
	public List<CheckChildPlanListVo> getCheckChildPlanList(Long planId) {
		List<Dict> problem = dictService.getList("fault_problem");
		Map<String, List<Dict>> collectMap = problem.stream().collect(Collectors.groupingBy(Dict::getDictKey));
		List<CheckChildPlanListVo> checkChildPlanList = baseMapper.getCheckChildPlanList(planId);
		for (CheckChildPlanListVo checkChildPlanListVo : checkChildPlanList) {
			checkChildPlanListVo.setStatusName(TaskStatusEnum.getTaskName(checkChildPlanListVo.getTypeStatus(), checkChildPlanListVo.getStatus()));
			if (checkChildPlanListVo.getProblemItem() != null) {
				List<String> problemItemNames = new ArrayList<>(16);
				String[] split = checkChildPlanListVo.getProblemItem().split(",");
				for (String key : split) {
					List<Dict> dicts = collectMap.get(key);
					if (dicts != null && dicts.size() > 0) {
						problemItemNames.add(dicts.get(0).getDictValue());
					}
				}
				checkChildPlanListVo.setProblemItemNames(String.join(",", problemItemNames));
			}
		}
		return checkChildPlanList;
	}


	/**
	 * 获取质检问题点的子工单信息
	 *
	 * @param planId
	 * @return
	 */
	private CheckChildPlanVo getCheckChildPlanVo(Long planId) {
		List<Long> planIds = new ArrayList<>(10);
		planIds.add(planId);
		List<CheckChildPlanVo> list = baseMapper.getCheckChildPlanVo(planIds);
		for (CheckChildPlanVo checkChildPlanVo : list) {
			checkChildPlanVo.setStatusName(TaskStatusEnum.getTaskName(checkChildPlanVo.getTypeStatus(), checkChildPlanVo.getStatus()));
		}
		return list.get(0);
	}
}
